package com.quwan.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quwan.common.query.LambdaQueryWrapperX;
import com.quwan.entity.TMenu;
import com.quwan.entity.TRoleMenu;
import com.quwan.manager.controller.dto.MenuZtree;
import com.quwan.manager.service.MenuService;
import com.quwan.mapper.TMenuMapper;
import com.quwan.mapper.TRoleMenuMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author laozhang
 * @date 2021/9/25 11:54
 */
@Service
@RequiredArgsConstructor
public class MenuServiceImpl implements MenuService {
    private static final int adminRole= 1;
    private final TMenuMapper menuMapper;
    private final TRoleMenuMapper roleMenuMapper;

    @Override
    public List<TMenu> getMenuListPage(String menuName) {
        LambdaQueryWrapper<TMenu> wrapper = new LambdaQueryWrapper<TMenu>().orderByAsc(TMenu::getPid).orderByAsc(TMenu::getId);
        if (StringUtils.isNotBlank(menuName)) {
            wrapper.like(TMenu::getMenuName, menuName);
        }
        List<TMenu> tMenus = menuMapper.selectList(new LambdaQueryWrapper<TMenu>()
                .select(TMenu::getId, TMenu::getMenuName)
                .eq(TMenu::getPid, 0).eq(TMenu::getMenuStatus, 1));
        List<TMenu> list = menuMapper.selectList(wrapper);
        Map<Integer, TMenu> parent = list.stream().filter(f -> f.getPid() == 0)
                .collect(Collectors.toMap(TMenu::getId, v -> v));
        list.forEach(m -> {
            String parentName = Optional.ofNullable(parent.get(m.getPid())).map(TMenu::getMenuName).orElse("菜单栏");
            m.setChildMenu(tMenus);
            m.setParentName(parentName);
        });

        return list;
    }

    @Override
    public List<TMenu> getMenuList(String menuName) {
        LambdaQueryWrapperX<TMenu> wrapper = new LambdaQueryWrapperX<TMenu>()
                .orderByDesc(TMenu::getAddTime);
        if (StringUtils.isNotBlank(menuName)) {
            wrapper.like(TMenu::getMenuName, menuName);
        }
        List<TMenu> res = menuMapper.selectList(wrapper);
        return res;
    }

    @Transactional
    @Override
    public boolean addMenu(TMenu menu) {
        int row = menuMapper.insert(menu.setAddTime(new Date()));
        int rrow = roleMenuMapper.insert(new TRoleMenu().setRoleId(adminRole).setMenuId(menu.getId()));
        return rrow == 1 && row == 1;
    }

    @Override
    public boolean updateMenu(TMenu menu) {
        return menuMapper.updateById(menu) == 1;
    }

    @Override
    public boolean delMenu(Integer id) {
        roleMenuMapper.delete(new QueryWrapper<>(new TRoleMenu().setMenuId(id).setRoleId(adminRole)));
        return menuMapper.deleteById(id) == 1;
    }

    @Override
    public List<TMenu> selectMenuListByRoleId(Integer roleId) {
        List<TMenu> menuList = menuMapper.selectMenuListByRoleId(roleId);
        List<TMenu> res = new ArrayList<TMenu>();
        for (TMenu menu : menuList) {
            if (menu.getPid().equals(0)) {
                getMenuChild(menu, menuList);
                res.add(menu);
            }
        }
        return res;
    }

    private TMenu getMenuChild(TMenu menu, List<TMenu> menuList) {
        for (TMenu tMenu : menuList) {
            if (menu.getId().equals(tMenu.getPid())) {
                menu.getChildMenu().add(tMenu);
            }
        }
        return menu;
    }

    @Override
    public List<MenuZtree> getZtreeMenuListByRoleId(Integer roleId) {
        List<Map<String, Object>> mapList = menuMapper.getCheckedMenuListByRoleId(roleId);
        List<MenuZtree> ztreeList = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            if (map.get("pid").equals(0)) {
                MenuZtree zt = new MenuZtree();
                zt.setId((Integer) map.get("id"));
                zt.setKey((Integer) (map.get("id")));
                zt.setPid((Integer) map.get("pid"));
                zt.setTitle(map.get("menuName") + "");
                if (map.get("checked").equals("false")) {
                    zt.setChecked(false);
                } else {
                    zt.setChecked(true);
                }
                zt = getZtreeMenuChild(zt, mapList);
                ztreeList.add(zt);
            }
        }
        return ztreeList;
    }

    @Override
    public List<TMenu> getParentMenuList() {
        return menuMapper.selectList(new LambdaQueryWrapper<TMenu>()
                .select(TMenu::getId, TMenu::getMenuName)
                .eq(TMenu::getPid, 0));
    }

    @Override
    public boolean status(Integer id, Integer status) {

        return menuMapper.updateById(new TMenu().setId(id).setMenuStatus(status)) == 1;
    }

    private MenuZtree getZtreeMenuChild(MenuZtree zt, List<Map<String, Object>> mapList) {
        for (Map<String, Object> map : mapList) {
            if (map.get("pid").equals(zt.getId())) {
                MenuZtree zrr = new MenuZtree();
                zrr.setId((Integer) map.get("id"));
                zrr.setKey((Integer) (map.get("id")));
                zrr.setPid((Integer) map.get("pid"));
                zrr.setTitle(map.get("menuName") + "");
                if (map.get("checked").equals("false")) {
                    zrr.setChecked(false);
                } else {
                    zrr.setChecked(true);
                }
                zt.getChildren().add(zrr);
            }
        }
        return zt;
    }
}
